package st.utils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;


public class LexicalProb {

	private static ArrayList<String> pairList = new ArrayList<String>();
	private static Map<String, Integer> tagCount = new HashMap<String, Integer>();
	private static Map<String, Integer> wordCount = new HashMap<String, Integer>();
	private static Map<String, Integer> tagProb = new HashMap<String, Integer>();
	private static Map<String, Integer> wordTagCount = new HashMap<String, Integer>();
	private static String unKnownWord = "<UNK>";
	private static StringBuffer words = new StringBuffer();
	
	
	public static void createLexicalProb(String filename) {
		
		readFile(filename);
		tagCounts();
		pairCounts();
		
	}
	
	
	public static double getLexicalProb(String word, String tag)
	{
		double prob = 0.0;
		double delta = 0.01;
		if(wordTagCount.containsKey(word + " " + tag))
		{
			prob = (double)( wordTagCount.get(word + " " + tag).intValue() + delta ) / (double)(tagCount.get(tag).intValue()+(delta*tagProb.get(tag).intValue())); 			
		}	
		else if(wordCount.containsKey(word))
		{
			prob = (double)delta / (double)(tagCount.get(tag).intValue()+(delta*tagProb.get(tag).intValue()));
		}
		
		else if(wordTagCount.containsKey("<UNK>" + " " + tag))
		{
			prob = (double)( wordTagCount.get("<UNK>" + " " + tag).intValue() + delta ) / (double)(tagCount.get(tag).intValue()+(delta*tagProb.get(tag).intValue()));
		}
		else
		{
			prob = (double)delta / (double)(tagCount.get(tag).intValue()+(delta*tagProb.get(tag).intValue()));
		}
		return prob;	
	}
	
	
	public static void readFile(String filename)
	{
		BufferedReader br = null;
		try 
		{
			br = new BufferedReader(new FileReader(filename));
			String word = null;
			while ((word = br.readLine()) != null)
			{
				String[] split = word.split(" ");
				String newWord = split[1].toLowerCase()+" "+split[0];
				pairList.add(newWord);			
			}
			
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				br.close();
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
			
	}
	
	public static void tagCounts()
	{
		for(int count = 0; count < pairList.size(); count++)
		{
			String newTag = pairList.get(count).split(" ")[1];
			String newWord = pairList.get(count).split(" ")[0];
			if(tagCount.containsKey(newTag))
			{
				int tagcount = tagCount.get(newTag).intValue()+1;
				tagCount.put(newTag, tagcount);
			}
			else
			{
				tagCount.put(newTag, new Integer(1));
			}
			
			if(wordCount.containsKey(newWord))
			{
				int wordcount = wordCount.get(newWord).intValue()+1;
				wordCount.put(newWord, wordcount);
			}
			else
			{
				wordCount.put(newWord, new Integer(1));
			}
		}
	}
	
	public static void pairCounts()
	{
		
		int size = pairList.size();
		int trainingSize = 4 * size / 5;
		
		for (int count = 0; count < trainingSize; count++)
		{
			String newPair = pairList.get(count);
			words.append(newPair.split(" ")[0]+" ");
			if (wordTagCount.containsKey(newPair)) 
			{		
				int pairCount = wordTagCount.get(newPair).intValue()+1;
				wordTagCount.put(newPair,new Integer(pairCount));
			}
			else
			{
				wordTagCount.put(newPair,new Integer(1));
			}
		}
		
		for (int count = trainingSize; count < size; count++)
		{
            
			String newPair = pairList.get(count);
			
			if (wordTagCount.containsKey(newPair)) 
			{		
				int pairCount = wordTagCount.get(newPair).intValue()+1;
				wordTagCount.put(newPair,new Integer(pairCount));			
			}
			else
			{				
				String word = newPair.split(" ")[0];
				String tag = newPair.split(" ")[1];
			
				if(words.toString().contains(word))
				{			
					wordTagCount.put(newPair,new Integer(1));
					
				}
				else
				{	
					String unkTag = unKnownWord+" "+tag;
					if (wordTagCount.containsKey(unkTag)) 
					{
						int tagCount = wordTagCount.get(unkTag).intValue()+1;
						wordTagCount.put(unkTag,new Integer(tagCount));
					}
					else
					{
							wordTagCount.put(unkTag,new Integer(1));
					}
				}
			}
		}
		Set<String> tags = tagCount.keySet();
		
		
		for (String t : tags)
		{
			int count = 0;	
		
			for (String s : wordTagCount.keySet())
			{
				if(s.contains(t))
				{
					count++;
				}
			}
			tagProb.put(t, new Integer(count));
		
		}
		
	}
	
	
	

}
